#!/usr/bin/env python
# -*- coding: utf-8 -*-
import time

cmd_keys = {'31': '数据上报', '32': '配置下发', '34': '事件上报', '39': '上报配置'}
keys = {'01': '设备id', '02': '设备SN', '03': '历史数据', '04': '上报数据频率', '05': '数据采集频率', '07': '设置大于温度值上报',
        '08': '设置小于温度值上报', '0A': '设置大于湿度值上报', '0B': '设置小于湿度值上报', '0D': '设置大于气压值上报',
        '0E': '设置小于气压值上报', '11': '固件版本号', '14': '实时联网事件', '15': '时间戳', '16': 'SIM卡号',
        '17': '低电量上报事件', '19': '设置温度单位', '1A': '硬件版本号', '1B': '事件重复通知频率', '1D': '断开设备连接',
        '22': '硬件版本号', '23': '协议字节替换', '24': '设备下次联网时间', '25': '设置MQTT连接', '26': '数据拼包命令',
        '27': '协议字节替换'}
strs = '4347311F01011000A9F49F95FF08B48B9CAB358FD34946E50210004530333031354437343944453632363503F600B688775C05009AC22F66274E9AC22F67274E9AC22F66274E9AC22F66274E9AC22F66274E9AC22F65274E9AC22F66274E9AC22F66274E9AC22F66274E9AC22F65274E9AC22F65274E9AC22F66274E9AC22F65274E9AC22F66274E9AC22F66274E9AC22F66274E9AC22F66274E9AC22F65274E9AC22F65274E9AC22F65274E9AC22F66274E9AC22F65274E9AC22F65274E9AC22F65274E9AC22F65274E9AC22F65274E9AC22F65274E9AC22F65274E9AC22F66274E9AC22F65274E9AC22F66274E9AC22F65274E9AC22F65274E9AC22F65274E9AC22F65274E9AC22F65274E9AC22F65274E9AC22F65274E9AC22F66274E9AC22F66274ED370'
str_2 = '43473113001d010000030c001c534d613c008932314a2540ef03'

def get_keys(data):
    """获取包头、命令、数据包、验证码、数据包长度"""
    sop = data[0:4]
    cmd = data[4:6]
    length = data[6:10]
    payload = data[10:-4]
    checksum = data[-4:]
    # print('get_keys', data, sop, cmd, length, payload, checksum)
    return sop, cmd, length, payload, checksum


def validate_length(length, payload):
    """验证数据包长度和数据包"""
    len_p = len(payload) // 2
    length_str = length[-2:] + length[:2]
    len_length = int(length_str, 16)
    if len_length != len_p:
        return False
    return True


def reverse_data(data_string):
    data_list = []
    while data_string:
        data_list.append(data_string[:2])
        data_string = data_string[2:]
    data_list.reverse()
    return ''.join(data_list)
# print(reverse_data('010234'))


def parsing_tem_pre_ele(item):
    tem_humidity = reverse_data(item[0:6])
    tem = (int(tem_humidity[:3], 16) - 500) / 10
    humidity = int(tem_humidity[3:], 16) / 10
    pre = int(reverse_data(item[6:10]), 16) / 100
    ele = int(reverse_data(item[10:12]), 16)
    return {'tem': tem, 'humidity': humidity, 'pre': pre, 'ele': ele}


def parsing_history_data(value):
    value_item = {}
    # 时间戳1~4
    timestamp = int(reverse_data(value[:8]), 16)

    # 数据存储间隔5~6
    time_interval = int(reverse_data(value[8:12]), 16)
    # 数据6字节一组
    data_value = value[12:]
    data_len = len(data_value)
    num = int(data_len / 12)
    value_item.update({'timestamp': timestamp, 'time_interval': time_interval, 'num': num})
    items = []
    now_time = timestamp
    for i in range(num):
        datetime = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(now_time))
        item = data_value[i*12:i * 12 + 12]
        result = parsing_tem_pre_ele(item)
        result.update({'timestamp': timestamp, 'datetime': datetime})
        items.append(result)
        now_time += time_interval
    value_item['items'] = items
    return value_item


def parsing_payload(payload):
    data_list = []
    while payload:
        # print('parsing_payload', payload)
        key = payload[:2]
        name = keys.get(key, 'None')
        length = reverse_data(payload[2:6])
        int_length = int(length, 16)
        value = payload[6: 6 + int_length*2]
        payload = payload[6 + int_length*2:]
        item = {'name': name, 'key': key, 'length': int_length, 'value': value}
        if key == '03':
            item['value'] = parsing_history_data(value)
        data_list.append(item)
    return data_list
# print(parsing_payload('011000A9F49F95FF08B48B9CAB358FD34946E50210004530333031354437343944453632363503F600B688775C05009AC22F66274E9AC22F67274E9AC22F66274E9AC22F66274E9AC22F66274E9AC22F65274E9AC22F66274E9AC22F66274E9AC22F66274E9AC22F65274E9AC22F65274E9AC22F66274E9AC22F65274E9AC22F66274E9AC22F66274E9AC22F66274E9AC22F66274E9AC22F65274E9AC22F65274E9AC22F65274E9AC22F66274E9AC22F65274E9AC22F65274E9AC22F65274E9AC22F65274E9AC22F65274E9AC22F65274E9AC22F65274E9AC22F66274E9AC22F65274E9AC22F66274E9AC22F65274E9AC22F65274E9AC22F65274E9AC22F65274E9AC22F65274E9AC22F65274E9AC22F65274E9AC22F66274E9AC22F66274E'))


def parsing(data):
    """主程序：解析协议内容"""
    sop, cmd, length, payload, checksum = get_keys(data)
    # print('parsing', sop, cmd, length, payload, checksum, data)
    flag = validate_length(length, payload)
    msg = {'msg': cmd_keys.get(cmd, 'None'), 'cmd': cmd, 'checksum': checksum, 'flag': flag}
    if not flag:
        msg.update({'msg': '数据长度不对，重试或等待下一次'})
        return msg
    if cmd != '31':
        return msg
    data_list = parsing_payload(payload)
    msg.update({'payload': data_list})
    return msg
# print(parsing(str_2))
